from Tkinter import *
from tkFileDialog import askopenfilename, askdirectory
import os
import zipFile

filename = ""
filenameonfocus = ""

def zipinfo(zip_parser):
    info_list = zip_parser.archiveinfo()
    return info_list

def gridupdate(info_list, filegrid):
    filegrid.clear_grid()
    filegrid.create_header()
    filegrid.create_grid(info_list)  

def openfilepanel(filegrid):
    global filename
    filename = askopenfilename(filetypes=[("allfiles","*"),("zipfiles","*.zip")])
    if filename != "":
        zip_parser = zipFile.ZipParser(filename)
        info_list = zipinfo(zip_parser)
        gridupdate(info_list, filegrid)
        zip_parser.close()

def addfile(filegrid):
    global filename
    filetoadd = askopenfilename(filetypes=[("allfiles","*")])
    if filetoadd != "":
        zip_parser = zipFile.ZipParser(filename)
        zip_parser.add(filetoadd)
        info_list = zipinfo(zip_parser)
        gridupdate(info_list, filegrid)
        zip_parser.close()

def extracttodir():
    global filename
    dirpath = askdirectory()
    if dirpath != "":
        zip_parser = zipFile.ZipParser(filename)
        zip_parser.extract(filenameonfocus, dirpath) 
        zip_parser.close()

def fileonfocus(event):
    global filenameonfocus 
    filenameonfocus = event.widget.get()

def closefile(filegrid):
    gridupdate([], filegrid)

def quitprogram(root):
    root.destroy()

# open file panel    
class OpenFile():

    def __init__ ( self ):
        self.root = Tk()
        self.root.title("Open a new file...")
        self.topFrame = Frame(self.root)
        self.bottomFrame = Frame(self.root)
        self.fileTree = Listbox(self.topFrame)
        self.fileDetail = Listbox(self.topFrame)
        self.buttonOpen = Button(self.bottomFrame, text="Open")
        self.buttonCancel = Button(self.bottomFrame, text="Cancel")
        self.fileTree.pack(side=LEFT)
        self.fileDetail.pack(side=LEFT, fill=X, expand=1)
        self.buttonOpen.pack(side=RIGHT)
        self.buttonCancel.pack(side=RIGHT)
        self.topFrame.pack(fill=BOTH, expand=1)
        self.bottomFrame.pack(fill=X, expand=1)
        self.root.geometry("300x300")
        self.root.mainloop()

    def get_tree( self ):
        os.listdir(STARTDIR)

        
class MainPanel():

    def __init__( self ):
        """contructor"""
        # main panel
        self.mainpanel = Tk()
        self.mainpanel.title("Zip file manager")
        
        # frames and the tricky canvas for scrollbar
        self.optionpanel = Frame(self.mainpanel)
        self.canvas = Canvas(self.mainpanel, borderwidth=0)
        self.gridpanel = Frame(self.canvas)

        # scroll bar with a trick using canvas
        self.vsb = Scrollbar(self.mainpanel, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)

        # file grid
        self.filegrid = FileGrid(self.gridpanel)

        # menu bar
        self.menubar = Menu(self.mainpanel)

        # menu bar: file
        self.filemenu = Menu(self.menubar, tearoff=0)
        self.filemenu.add_command(label="Open", command=lambda g=self.filegrid: openfilepanel(g))
        self.filemenu.add_command(label="Close",command=lambda g=self.filegrid: closefile(g))
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Exit", command=lambda r=self.mainpanel: quitprogram(r))
        self.menubar.add_cascade(label="File", menu=self.filemenu)
        self.mainpanel.config(menu=self.menubar)

        # buttons
        self.buttondelete = Button(self.optionpanel, text="Delete")
        self.buttonadd = Button(self.optionpanel, text="Add", command=lambda g=self.filegrid: addfile(g))
        self.buttonExtract = Button(self.optionpanel, text="Extract", command=extracttodir)
    
        # create headers in file grid
        self.filegrid.create_header()

        # packing ...
        self.optionpanel.pack(fill=X)
        self.buttondelete.pack(side=LEFT)
        self.buttonadd.pack(side=LEFT)
        self.buttonExtract.pack(side=LEFT)
        
        self.vsb.pack(side="right", fill="y")
        self.canvas.pack(side="left", fill="both", expand=True)
        self.canvas.create_window((4,4), window=self.gridpanel, anchor="nw", tags="self.gridpanel")
        self.gridpanel.bind("<Configure>", self.OnFrameConfigure)
        
        #self.gridpanel.pack(fill=BOTH, expand=1)

        self.mainpanel.geometry("640x400")
        self.mainpanel.mainloop()


    def OnFrameConfigure(self, event):
        """Reset the scroll region to encompass the inner frame"""
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))
        
class FileGrid():

    
    def __init__ ( self, root ):
        """constructor"""
        self.root = root

    def create_header(self):
        """creates the grids header"""
        filename = Entry(self.root)
        filename.insert(END, "File Name")
        filename.grid(row=0, column=0, sticky=NSEW)
        filesize = Entry(self.root)
        filesize.insert(END, "File Size")
        filesize.grid(row=0, column=1, sticky=NSEW)
        filecompsize = Entry(self.root)
        filecompsize.insert(END, "File Compressed Size")
        filecompsize.grid(row=0, column=2, sticky=NSEW)
        filedate = Entry(self.root)
        filedate.insert(END, "File Date")
        filedate.grid(row=0, column=3, sticky=NSEW)

    def create_grid(self, info_list):
        """creates the grid body""" 
        size = len(info_list)
        i = 1
        for info in info_list:
            gridEntryFileName = Entry(self.root)
            gridEntryFileName.grid(row=i, column=0, sticky=NSEW)
            gridEntryFileName.insert(END, info.filename)
            self.bind(gridEntryFileName)
            
            gridEntryFileSize = Entry(self.root)
            gridEntryFileSize.grid(row=i, column=1, sticky=NSEW)
            gridEntryFileSize.insert(END, info.filesize)

            gridEntryFileCompSize = Entry(self.root)
            gridEntryFileCompSize.grid(row=i, column=2, sticky=NSEW)
            gridEntryFileCompSize.insert(END, info.compresssize)

            gridEntryDateTime = Entry(self.root)
            gridEntryDateTime.grid(row=i, column=3, sticky=NSEW)
            gridEntryDateTime.insert(END, info.datetime)
            
            i += 1        

    def clear_grid(self):
        """clears the grid"""
        items = self.root.children
        for item in items:
            items[item].grid_remove()

    def bind(self, entry):
        """binds the FocusIn event"""
        entry.bind('<FocusIn>', fileonfocus)

            
MainPanel()






        
    



